package com.example.feature.demo.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;

@Component
public class FileUtil {

    private static final Logger logger = LoggerFactory.getLogger(FileUtil.class);

    public void downFile(HttpServletRequest request, HttpServletResponse response, String filename) throws IOException {

        OutputStream out = null;
        BufferedInputStream bis = null;
        try {
            bis = new BufferedInputStream(this.getClass().getResourceAsStream("/file/" + filename));

            // 解决文件名乱码问题，获取浏览器类型，转换对应文件名编码格式，IE要求文件名必须是utf-8, firefo要求是iso-8859-1编码
            String agent = request.getHeader("user-agent");
            if (agent.contains("FireFox")) {
                filename = new String(filename.getBytes("UTF-8"), "iso-8859-1");
            } else {
                filename = URLEncoder.encode(filename, "UTF-8");
            }
            // 设置下载文件的mineType，告诉浏览器下载文件类型
            String mineType = request.getServletContext().getMimeType(filename);
            response.setContentType(mineType);
            response.setCharacterEncoding("UTF-8");
            // 设置一个响应头，无论是否被浏览器解析，都下载
            response.setHeader("Content-disposition", "attachment; filename=" + filename);
            // 将要下载的文件内容通过输出流写到浏览器
            out = response.getOutputStream();
            int len = 0;
            byte[] buffer = new byte[1024];
            while ((len = bis.read(buffer)) > 0) {
                out.write(buffer, 0, len);
                out.flush();
            }
        } catch (IOException e) {
            logger.error("failed to downFile:", e);
        } finally {
            if (bis != null) {
                bis.close();
            }
            if (out != null) {
                out.close();
            }
        }
    }

    /**
     * 判断指定的文件或文件夹删除是否成功
     *
     * @param FileName 文件或文件夹的路径
     * @return true or false 成功返回true，失败返回false
     */
    public static boolean deleteAnyone(String fileName) {
        File file = new File(fileName);//根据指定的文件名创建File对象
        if (!file.exists()) {  //要删除的文件不存在
            logger.info("文件{}不存在，删除失败！", fileName);
            return false;
        } else { //要删除的文件存在
            if (file.isFile()) { //如果目标文件是文件
                return deleteFile(fileName);
            } else {  //如果目标文件是目录
                return deleteDir(fileName);
            }
        }
    }


    /**
     * 判断指定的文件删除是否成功
     *
     * @param FileName 文件路径
     * @return true or false 成功返回true，失败返回false
     */
    public static boolean deleteFile(String fileName) {
        File file = new File(fileName);//根据指定的文件名创建File对象
        if (file.exists() && file.isFile()) { //要删除的文件存在且是文件
            if (file.delete()) {
                logger.info("文件{}删除成功！", fileName);
                return true;
            } else {
                logger.info("文件{}删除失败！", fileName);
                return false;
            }
        } else {
            logger.info("文件{}不存在，删除失败！", fileName);
            return false;
        }
    }


    /**
     * 删除指定的目录以及目录下的所有子文件
     *
     * @param dirName is 目录路径
     * @return true or false 成功返回true，失败返回false
     */
    public static boolean deleteDir(String dirName) {
        //dirName不以分隔符结尾则自动添加分隔符
        if (dirName.endsWith(File.separator)) {
            dirName = dirName + File.separator;
        }
        File file = new File(dirName);//根据指定的文件名创建File对象
        if (!file.exists() || (!file.isDirectory())) { //目录不存在或者
            logger.info("目录删除失败{}目录不存在！", dirName);
            return false;
        }
        File[] fileArrays = file.listFiles();//列出源文件下所有文件，包括子目录
        for (int i = 0; i < fileArrays.length; i++) {//将源文件下的所有文件逐个删除
            deleteAnyone(fileArrays[i].getAbsolutePath());
        }
        if (file.delete())//删除当前目录
            logger.info("目录{}删除成功！", dirName);
        return true;
    }
}
